﻿#include<stdexcept>
#include<cstring>
#include"SerialBuffer.hpp"

namespace MMFSerialize{

    SerialInBuffer::SerialInBuffer(char* data, uint32_t size, uint32_t startIdx)
        : mBuff(data, size)
        , mPos(startIdx)
    {

    }

    SerialInBuffer::SerialInBuffer(const std::vector<char>& data, uint32_t startIdx)
        : mBuff(data.data(), data.size())
        , mPos(startIdx)
    {

    }

    SerialInBuffer::~SerialInBuffer()
    {

    }

    void SerialInBuffer::Push(bool val)
    {
        bool* data = (bool*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(int8_t val)
    {
        int8_t* data = (int8_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(uint8_t val)
    {
        uint8_t* data = (uint8_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(int16_t val)
    {
        int16_t* data = (int16_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(uint16_t val)
    {
        uint16_t* data = (uint16_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(int32_t val)
    {
        int32_t* data = (int32_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(uint32_t val)
    {
        uint32_t* data = (uint32_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(int64_t val)
    {
        int64_t* data = (int64_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(uint64_t val)
    {
        uint64_t* data = (uint64_t*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(float val)
    {
        float* data = (float*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(double val)
    {
        double* data = (double*)(mBuff.data() + mPos);
        std::memcpy(data, &val, sizeof(val));
        mPos = mPos + sizeof(val);
    }

    void SerialInBuffer::Push(const std::string& val)
    {
        uint32_t dataPos = mPos;

        //添加长度
        int* dataLen = (int*)(mBuff.data() + dataPos);
        *dataLen = (uint32_t)val.length();
        dataPos += sizeof(uint32_t);

        //拷贝数据
        char* data = (char*)mBuff.data() + dataPos;
        std::memcpy(data, val.data(), *dataLen);
        dataPos += *dataLen;

        mPos = dataPos;
    }

    void SerialInBuffer::Push(const std::string_view val)
    {
        uint32_t dataPos = mPos;

        //添加长度
        int* dataLen = (int*)(mBuff.data() + dataPos);
        *dataLen = (uint32_t)val.length();
        dataPos += sizeof(uint32_t);

        //拷贝数据
        char* data = (char*)mBuff.data() + dataPos;
        std::memcpy(data, val.data(), *dataLen);
        dataPos += *dataLen;

        mPos = dataPos;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, bool val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, int8_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, uint8_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, int16_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, uint16_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, int32_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, uint32_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, int64_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, uint64_t val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, float val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, double val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, const std::string& val)
    {
        buff.Push(val);
        return buff;
    }

    SerialInBuffer& operator>>(SerialInBuffer& buff, const std::string_view& val)
    {
        buff.Push(val);
        return buff;
    }

    SerialOutBuffer::SerialOutBuffer(char* buff, uint32_t buffSize)
        : mBuff(buff, buffSize)
        , mPos(0)
    {
        
    }

    SerialOutBuffer::SerialOutBuffer(const std::string_view& buff)
        : mBuff(buff)
        , mPos(0)
    {

    }

    SerialOutBuffer::~SerialOutBuffer()
    {

    }

    void SerialOutBuffer::Pop(bool& val)
    {
        uint32_t dataSize = sizeof(val);
        bool* data = (bool*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(int8_t& val)
    {
        uint32_t dataSize = sizeof(val);
        int8_t* data = (int8_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(uint8_t& val)
    {
        uint32_t dataSize = sizeof(val);
        uint8_t* data = (uint8_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(int16_t& val)
    {
        uint32_t dataSize = sizeof(val);
        int16_t* data = (int16_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(uint16_t& val)
    {
        uint32_t dataSize = sizeof(val);
        uint16_t* data = (uint16_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(int32_t& val)
    {
        uint32_t dataSize = sizeof(val);
        int32_t* data = (int32_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(uint32_t& val)
    {
        uint32_t dataSize = sizeof(val);
        uint32_t* data = (uint32_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(int64_t& val)
    {
        uint32_t dataSize = sizeof(val);
        int64_t* data = (int64_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(uint64_t& val)
    {
        uint32_t dataSize = sizeof(val);
        uint64_t* data = (uint64_t*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(float& val)
    {
        uint32_t dataSize = sizeof(val);
        float* data = (float*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(double& val)
    {
        uint32_t dataSize = sizeof(val);
        double* data = (double*)(mBuff.data() + mPos);
        val = *data;
        mPos += dataSize;
    }

    void SerialOutBuffer::Pop(std::string& val)
    {
        uint32_t dataSize = sizeof(uint32_t);
        uint32_t strLen = *(uint32_t*)(mBuff.data() + mPos);    //获取长度

        //去掉长度
        mPos += dataSize;      

        //拷贝数据
        val.resize(strLen);
        memcpy(val.data(), mBuff.data() + mPos, strLen);

        //字符串的数据       
        mPos += strLen;
    }

    void SerialOutBuffer::Pop(std::string_view& val)
    {
        uint32_t dataSize = sizeof(uint32_t);
        uint32_t strLen = *(uint32_t*)(mBuff.data() + mPos);    //获取长度

        //去掉长度
        mPos += dataSize;

        //拷贝数据
        if (dataSize > val.size())
            throw std::length_error((__FILE__ +  std::to_string(__LINE__)).c_str());
        else
        {
            memcpy((void*)val.data(), mBuff.data() + mPos, strLen);
            ((char*)val.data())[strLen] = 0;
        }

        //字符串的数据       
        mPos += strLen;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, bool& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, int8_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, uint8_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, int16_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, uint16_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, int32_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, uint32_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, int64_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, uint64_t& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, float& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, double& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, std::string& val)
    {
        buff.Pop(val);
        return buff;
    }

    SerialOutBuffer& operator<<(SerialOutBuffer& buff, std::string_view& val)
    {
        buff.Pop(val);
        return buff;
    }
}
